home *** CD-ROM | disk | FTP | other *** search
/ Beginning Mac Programming / Beginning Mac Programming.bin / pc / Open Me for REALbasic 3 / REALbasic 3.2 / Goodies / 3rd Party Demos / 3rd Party Plugins / Misc / PEVocoder 1.0 (PPC) / PEVocodePlugin Source Code / wave.cp < prev    next >
Encoding:
Text File  |  2000-11-21  |  6.4 KB  |  277 lines

  1. /******************************************************************************
  2.  * $Id: wave.c,v 1.2 1998/09/13 00:21:18 emanuel Exp $
  3.  * Copyright (C) 1998 Emanuel Borsboom <emanuel@zerius.com>
  4.  * Permission is granted to make any use of this code subject to the condition
  5.  * that all copies contain this notice and an indication of what has been
  6.  * changed.
  7.  *****************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. /*#include <sys/errno.h>*/
  13. #include <errno.h>
  14. #include "config.h"
  15. #include "wave.h"
  16. #include "extended.h"
  17. #include "error.h"
  18.  
  19. #include "aiff.h"
  20. #include "riff.h"
  21.  
  22. static struct {
  23.   WAVE_FILE *(*open_func)(FILE *fp, WAVE_INFO *info);
  24.   WAVE_FILE *(*create_func)(FILE *fp, WAVE_INFO *info);
  25.   void (*close_func)(WAVE_FILE *file);
  26. } wave_formats[] = 
  27. {
  28.   {aiff_open, aiff_create, aiff_close},
  29.   {riff_open, riff_create, riff_close}
  30. };
  31.  
  32. WAVE_FILE *wave_open(char *filename, WAVE_INFO *info)
  33. {
  34.   FILE *fp;
  35.   int i;
  36.  
  37.   fp = error_fopen(filename, "rb");
  38.  
  39.   for (i = 0; i < WAVE_NUM_FORMATS; ++i) {
  40.     if (wave_formats[i].open_func != NULL)
  41.       {
  42.         WAVE_FILE *file;
  43.         info->format = (WAVE_FORMAT) i;
  44.         file = wave_formats[i].open_func(fp, info);
  45.         if (file != NULL)
  46.           {
  47.             file->bits = info->bits;
  48.             file->format = info->format;
  49.             file->length = info->length;
  50.             file->position = 0;
  51.             file->open_mode = WAVE_READ_MODE;
  52.             file->fp = fp;
  53.             file->data_offset = ftell(fp);
  54.             return file;
  55.           }
  56.         fseek(fp, 0, SEEK_SET);
  57.       }
  58.   }
  59.  
  60.   fclose(fp);
  61.   error("wave_open %s: unknown format", filename);
  62.   return NULL;
  63. }
  64.  
  65. WAVE_FILE *wave_open_specific(char *filename, WAVE_INFO *info)
  66. {
  67.   FILE *fp;
  68.   WAVE_FILE *file;
  69.   
  70.   fp = error_fopen(filename, "rb");
  71.  
  72.   file = wave_formats[info->format].open_func(fp, info);
  73.   if (file == NULL) return NULL;
  74.   file->bits = info->bits;
  75.   file->format = info->format;
  76.   file->length = info->length;
  77.   file->position = 0;
  78.   file->open_mode = WAVE_READ_MODE;
  79.   file->fp = fp;
  80.   file->data_offset = ftell(fp);
  81.   return file;
  82. }
  83.  
  84. WAVE_FILE *wave_create(char *filename, WAVE_INFO *info)
  85. {
  86.   FILE *fp;
  87.   WAVE_FILE *file;
  88.  
  89.   fp = error_fopen(filename, "wb");
  90.  
  91.   file = wave_formats[info->format].create_func(fp, info);
  92.   if (file == NULL) return NULL;
  93.   file->bits = info->bits;
  94.   file->format = info->format;
  95.   file->open_mode = WAVE_WRITE_MODE;
  96.   file->length = 0;
  97.   file->position = 0;
  98.   file->fp = fp;
  99.   file->data_offset = ftell(fp);
  100.   return file;
  101. }
  102.  
  103. void wave_seek(WAVE_FILE *file, INT position)
  104. {
  105.   if (file->open_mode == WAVE_WRITE_MODE)
  106.     error("wave_seek: seek only supported for files opened in read mode");
  107.  
  108.   if (position > file->length)
  109.     error("wave_seek: attempting to position out of file");
  110.  
  111.   fseek(file->fp, file->data_offset + position * ((file->bits + 7) / 8),
  112.         SEEK_SET);
  113.   file->position = position;
  114. }
  115.  
  116. void wave_close(WAVE_FILE *file)
  117. {
  118.   if (wave_formats[file->format].close_func != NULL)
  119.     wave_formats[file->format].close_func(file);
  120.   fclose(file->fp);
  121.   free(file);
  122. }
  123.  
  124. size_t wave_read(WAVE_FILE *file, SAMPLE *buffer, size_t length)
  125. {
  126.   size_t count = 0;
  127.  
  128.   if (feof(file->fp))
  129.     return 0;
  130.  
  131.   if (file->length - file->position < length)
  132.     length = file->length - file->position;
  133.  
  134.   if (file->bits == 8)
  135.     {
  136.       for (count = 0; count < length; ++count)
  137.         buffer[count] = (BYTE)(getc(file->fp) - file->sample_offset);
  138.     }
  139.   else if (file->bits == 16)
  140.     { 
  141.       if (file->is_big_endian)
  142.         {
  143.           for (count = 0; count < length; ++count)
  144.             buffer[count] = (SHORT)(wave_read_short_big(file->fp)
  145.                                     - file->sample_offset);
  146.         }
  147.       else
  148.         {
  149.           for (count = 0; count < length; ++count)
  150.             buffer[count] = (SHORT)(wave_read_short_little(file->fp)
  151.                                     - file->sample_offset);
  152.         }
  153.     }
  154.   else
  155.     {
  156.       error("wave_read: only 8-bit and 16-bit audio supported");
  157.     }
  158.  
  159.   if (ferror(file->fp))
  160.     error("wave_read: read error: %s", strerror(errno));
  161.  
  162.   file->position += count;
  163.   return count;
  164. }
  165.  
  166. void wave_write(WAVE_FILE *file, SAMPLE *buffer, size_t length)
  167. {
  168.   size_t count = 0;
  169.  
  170.   if (file->bits == 8)
  171.     {
  172.       for (count = 0; count < length; ++count)
  173.         putc(buffer[count] + file->sample_offset, file->fp);
  174.     }
  175.   else if (file->bits == 16)
  176.     {
  177.       if (file->is_big_endian)
  178.         {
  179.           for (count = 0; count < length; ++count)
  180.             wave_write_short_big(buffer[count] + file->sample_offset, file->fp);
  181.         }
  182.       else
  183.         {
  184.           for (count = 0; count < length; ++count)
  185.             wave_write_short_little(buffer[count] + file->sample_offset, file->fp);
  186.         }
  187.     }
  188.   else
  189.     {
  190.       error("wave_write: only 8-bit and 16-bit audio supported");
  191.     }
  192.  
  193.   if (ferror(file->fp))
  194.     error("wave_write: write error: %s", strerror(errno));
  195.  
  196.   file->length += count;
  197.   file->position += count;
  198. }
  199.  
  200. INT wave_read_int_big(FILE *fp)
  201. {
  202.   int a, b, c, d;
  203.   a = getc(fp); b = getc(fp); c = getc(fp); d = getc(fp);
  204.   return (a << 24) | (b << 16) | (c << 8) | d;
  205. }
  206.  
  207. void wave_write_int_big(INT i, FILE *fp)
  208. {
  209.   int a, b, c, d;
  210.   a = (i >> 24) & 0xff;
  211.   b = (i >> 16) & 0xff;
  212.   c = (i >> 8) & 0xff;
  213.   d = i & 0xff;
  214.   putc(a, fp); putc(b, fp); putc(c, fp); putc(d, fp);
  215. }
  216.  
  217. INT wave_read_int_little(FILE *fp)
  218. {
  219.   int a, b, c, d;
  220.   a = getc(fp); b = getc(fp); c = getc(fp); d = getc(fp);
  221.   return (d << 24) | (c << 16) | (b << 8) | a;
  222. }
  223.  
  224. void wave_write_int_little(INT i, FILE *fp)
  225. {
  226.   int a, b, c, d;
  227.   a = (i >> 24) & 0xff;
  228.   b = (i >> 16) & 0xff;
  229.   c = (i >> 8) & 0xff;
  230.   d = i & 0xff;
  231.   putc(d, fp); putc(c, fp); putc(b, fp); putc(a, fp);
  232. }
  233.  
  234. SHORT wave_read_short_big(FILE *fp)
  235. {
  236.   int a, b;
  237.   a = getc(fp); b = getc(fp);
  238.   return (a << 8) | b;
  239. }
  240.  
  241. void wave_write_short_big(SHORT i, FILE *fp)
  242. {
  243.   int a, b;
  244.   a = (i >> 8) & 0xff;
  245.   b = i & 0xff;
  246.   putc(a, fp); putc(b, fp);
  247. }
  248.  
  249. SHORT wave_read_short_little(FILE *fp)
  250. {
  251.   int a, b;
  252.   a = getc(fp); b = getc(fp);
  253.   return (b << 8) | a;
  254. }
  255.  
  256. void wave_write_short_little(SHORT i, FILE *fp)
  257. {
  258.   int a, b;
  259.   a = (i >> 8) & 0xff;
  260.   b = i & 0xff;
  261.   putc(b, fp); putc(a, fp);
  262. }
  263.  
  264. REAL wave_read_extended(FILE *fp)
  265. {
  266.   unsigned char bytes[10];
  267.   fread(bytes, 10, 1, fp);
  268.   return ConvertFromIeeeExtended(bytes);
  269. }
  270.  
  271. void wave_write_extended(REAL e, FILE *fp)
  272. {
  273.   unsigned char bytes[10];
  274.   ConvertToIeeeExtended(e, bytes);
  275.   fwrite(bytes, 10, 1, fp);
  276. }
  277.